package com.kun.config.interceptor;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.kun.common.Constants;
import com.kun.common.annotation.PermissionAuthentication;
import com.kun.common.exception.MyException;
import com.kun.index.entity.User;
import com.kun.index.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@Component
public class DiyJwtInterceptor implements HandlerInterceptor {
    @Autowired
    private UserServiceImpl userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

//        1.从请求中获取token
        String token = request.getHeader("token");

//        2.如果不映射到方法直接通过(请求资源)
        if(!(handler instanceof HandlerMethod)){
            return true;
        } else{
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            PermissionAuthentication annotation = handlerMethod.getMethodAnnotation(PermissionAuthentication.class);
            if (annotation!=null){
                return true;
            }

        }

//        3.判断token是否存在
        if (StringUtils.isEmpty(token)){
            throw new MyException(Constants.CODE_303,"无token，登录失败");
        }

//        4.获取token的userId
        int userId;
        try{
            String userId_str = JWT.decode(token).getAudience().get(0);
            userId = Integer.parseInt(userId_str);
        }catch (Exception e){
            throw new MyException(Constants.CODE_303,"token认证失败，不存在该用户");
        }

//        5.根据userId查询数据库，查询用户
        User user = userService.queryUserById(userId);
        if (user==null){
            throw new MyException(Constants.CODE_303,"token认证失败，不存在该用户");
        }

//        6.密码匹配
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
        try{
            jwtVerifier.verify(token);
        }catch (Exception e){
            throw new MyException(Constants.CODE_303,"token认证失败，密码错误");
        }
        return true;
    }

}
